package process

import (
	msg01 "chat/common/msg"
	"chat/utils"
	"encoding/binary"
	"encoding/json"
	"fmt"
	"net"
	"os"
)

type UserProcess struct {
}

func (this *UserProcess) Login(userId int, pwd string) (err error) {
	fmt.Printf("userId=%v,pwd=%v\n", userId, pwd)
	// 连接服务器
	conn, err := net.Dial("tcp", "127.0.0.1:8888")
	if err != nil {
		fmt.Println("net.Dial error = ", err)
		return
	}
	defer conn.Close()
	// 发送消息
	// 1 构建消息
	var msg msg01.Message
	// 消息类型
	msg.Type = msg01.LoginMsgType
	// 2 消息结构体
	var loginMsg msg01.LoginMsg
	loginMsg.UserId = userId
	loginMsg.Pwd = pwd
	// 3 序列化 msg.loginMsg 消息体
	data, err := json.Marshal(loginMsg)
	if err != nil {
		fmt.Println("login json.Marshal error = ", err)
		return
	}
	// 4 消息内容
	msg.Data = string(data)
	// 5 msg 序列化
	data, err = json.Marshal(msg)
	if err != nil {
		fmt.Println("login json.Marshal msg error = ", err)
		return
	}
	// 发送消息到server
	// 先发送消息长度 -- 获取data长度，再转为切片
	var pkgLen uint32
	pkgLen = uint32(len(data))
	var buf [4]byte
	binary.BigEndian.PutUint32(buf[0:4], pkgLen)
	n, err := conn.Write(buf[:4])
	if n != 4 || err != nil {
		fmt.Println("login conn.Write dataLen error = ", err)
		return
	}
	fmt.Printf("客户端发送长度=%v,内容=%v\n", len(data), string(data))
	// 发送消息本身
	_, err = conn.Write(data)
	if err != nil {
		fmt.Println("login conn.Write data error = ", err)
		return
	}

	// 处理服务端消息
	tf := &utils.Transfer{
		Conn: conn,
	}
	message, err := tf.ReadPkg()
	if err != nil {
		fmt.Println("login ReadPkg data error = ", err)
		return
	}
	var loginRes msg01.LoginResMsg
	err = json.Unmarshal([]byte(message.Data), &loginRes)
	if err != nil {
		fmt.Println("login ReadPkg Unmarshal data error = ", err)
		return
	}
	if loginRes.Code == 200 {
		// 登录成功
		// 初始化当前用户
		CurrUser.UserId = userId
		CurrUser.Conn = conn
		CurrUser.UserStatus = msg01.UserOnline

		fmt.Println("当前在线用户列表：")
		for _, v := range loginRes.UserIds {
			if v == userId {
				continue
			}
			fmt.Println("用户id:", v)
			// 完成客户端 clientOnlineUsers 初始化
			user := &msg01.User{
				UserId:     v,
				UserStatus: msg01.UserOnline,
			}
			clientOnlineUsers[v] = user
		}
		// 显示二级菜单
		// 启动协程 保存和服务端的通讯 接受并显示在客户端
		go serverProcess(conn)

		for {
			ShowLoginSuccessMenu()
		}
	} else {
		fmt.Println(loginRes.Error)
	}
	return
}

func (this *UserProcess) Register(userId int, pwd string, username string) (err error) {
	fmt.Printf("Register userId=%v,pwd=%v,username=%v\n", userId, pwd, username)
	// 连接服务器
	conn, err := net.Dial("tcp", "127.0.0.1:8888")
	if err != nil {
		fmt.Println("Register net.Dial error = ", err)
		return
	}
	defer conn.Close()
	// 发送消息
	// 1 构建消息
	var msg msg01.Message
	// 消息类型
	msg.Type = msg01.RegisterMsgType
	// 2 消息结构体
	var register msg01.RegisterMsg
	register.User.UserId = userId
	register.User.Username = username
	register.User.Pwd = pwd
	// 3 序列化 消息体
	data, err := json.Marshal(register)
	if err != nil {
		fmt.Println("Register json.Marshal error = ", err)
		return
	}
	// 4 消息内容
	msg.Data = string(data)
	// 5 msg 序列化
	data, err = json.Marshal(msg)
	if err != nil {
		fmt.Println("Register json.Marshal msg error = ", err)
		return
	}

	// 发送消息到server
	// 先发送消息长度 -- 获取data长度，再转为切片---注意是引用&
	tf := &utils.Transfer{
		Conn: conn,
	}

	err = tf.WritePkg(data)
	if err != nil {
		fmt.Println("Register WritePkg data error = ", err)
		return
	}

	message, err := tf.ReadPkg()
	if err != nil {
		fmt.Println("Register ReadPkg data error = ", err)
		return
	}

	var registerResponse msg01.RegisterResMsg
	err = json.Unmarshal([]byte(message.Data), &registerResponse)
	if err != nil {
		fmt.Println("Register ReadPkg Unmarshal data error = ", err)
		return
	}
	if registerResponse.Code == 200 {
		fmt.Println("注册成功,可以使用密码登陆")
	} else {
		fmt.Println(registerResponse.Error)
	}
	os.Exit(0)
	return
}
